package com.hzy.fivepalace.admin.service;

import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hzy.fivepalace.common.consts.RedisKeyConsts;
import com.hzy.fivepalace.common.exception.AppException;
import com.hzy.fivepalace.common.service.redis.RedisCache;
import com.hzy.fivepalace.common.type.VipTypeEnums;
import com.hzy.fivepalace.common.util.OrderUtils;
import com.hzy.fivepalace.common.util.ResponseUtil;
import com.hzy.fivepalace.common.util.TableDataInfo;
import com.hzy.fivepalace.db.dao.DtsPointsDetailMapper;
import com.hzy.fivepalace.db.dao.DtsUserMapper;
import com.hzy.fivepalace.db.dao.DtsWithdrawRecordsMapper;
import com.hzy.fivepalace.db.dao.ex.AppUserCommissionDetaiMapperEx;
import com.hzy.fivepalace.db.dao.ex.DtsUserMapperEx;
import com.hzy.fivepalace.db.domain.*;
import com.hzy.fivepalace.db.vo.wx.WxUserCommissionDetailDto;
import com.hzy.fivepalace.db.vo.wx.WxUserTeamVo;
import com.hzy.fivepalace.db.vo.wx.WxUserWithdrawRecordsDto;
import com.hzy.fivepalace.db.vo.wx.WxWithdrawRecordsVo;
import jodd.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信用户服务
 */
@Service
public class AdminWxUserService {

    @Resource
    private DtsUserMapper userMapper;

    @Resource
    private Redisson redisson;

    @Resource
    private RedisCache redisCache;

    @Resource
    private DtsUserMapperEx dtsUserMapperEx;

    @Resource
    private DtsPointsDetailMapper dtsPointsDetailMapper;

    @Resource
    private AppUserCommissionDetaiMapperEx userCommissionDetaiMapperEx;

    @Resource
    private DtsWithdrawRecordsMapper dtsWithdrawRecordsMapper;

    @Resource
    private AliPayService aliPayService;

    /**
     * 获取提现记录列表
     *
     * @param page
     * @param size
     * @param withdrawRecords
     * @return
     */
    public TableDataInfo getWithdrawRecordsList(Integer page, Integer size, WxWithdrawRecordsVo withdrawRecords) {


        Page p = PageHelper.startPage(page, size);
        List<DtsWithdrawRecordsWithBLOBs> list = dtsWithdrawRecordsMapper.getWithdrawRecordsList(withdrawRecords);

        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }

    /**
     * 审核提现(状态为0调用)
     *
     * @param id
     * @param status 状态:2通过,3拒绝
     * @param msg    状态为3可以传入
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Object auditWithdraw(Integer id, Integer status, String msg) {
        if (null == id || id.intValue() < 1) {
            return ResponseUtil.fail("id为空");
        }
        RLock lock = redisson.getLock("admin:auditWithdraw:" + id);
        if (lock.isLocked()) {
            return ResponseUtil.frequent("其他管理员操作中,请稍后再试");
        }
        lock.lock(120, TimeUnit.SECONDS);
        if (null == status) {
            lock.unlock();
            return ResponseUtil.fail("请选择审核状态");
        }
        if (status.intValue() != 2 && status.intValue() != 3) {
            lock.unlock();
            return ResponseUtil.fail("状态错误");
        }
        DtsWithdrawRecordsWithBLOBs withdrawRecords = dtsWithdrawRecordsMapper.selectByPrimaryKey(id);
        if (null == withdrawRecords) {
            lock.unlock();
            return ResponseUtil.fail("提现记录不存在");
        }
        if (withdrawRecords.getStatus().intValue() != 0) {
            lock.unlock();
            return ResponseUtil.fail("当前状态不支持操作");
        }

        if (status.intValue() == 2) {
            msg = "";
        } else {
            if (StringUtils.isBlank(msg)) {
                msg = "审核被拒,嗨币已退还";
            } else {
                msg = msg + ",嗨币已退还";
            }
        }
        DtsWithdrawRecordsWithBLOBs withdrawRecordsUpd = new DtsWithdrawRecordsWithBLOBs();
        withdrawRecordsUpd.setId(id);
        withdrawRecordsUpd.setStatus(status);
        withdrawRecordsUpd.setRefuseMsg(msg);
        withdrawRecordsUpd.setUpdateTime(LocalDateTime.now());
        dtsWithdrawRecordsMapper.updateByPrimaryKeySelective(withdrawRecordsUpd);
        if (status.intValue() == 2) {//审核通过打款

            //支付宝打款
            try {
                AlipayFundTransUniTransferResponse response = aliPayService.transUniTransfer(OrderUtils.generateOrderNo(), withdrawRecords.getAmount(), "嗨币提现", withdrawRecords.getAlipayAccount(), withdrawRecords.getAlipayName());
                if (!response.isSuccess()) {
                    lock.unlock();
                    throw new AppException("支付宝服务异常," + response.getSubMsg());
                }
            } catch (Exception e) {
                lock.unlock();
                throw new AppException("支付宝服务错误," + e.getMessage());
            }

        } else {//不通过退还
            dtsUserMapperEx.addUserCommission(withdrawRecords.getUserId(), withdrawRecords.getAmount());

        }

        lock.unlock();
        return ResponseUtil.ok("操作成功");
    }

    public Object bindReUser(Integer userId,String reUserPhone){
        if(null==userId){
            return ResponseUtil.fail("请选择用户");
        }
        if(StringUtils.isBlank(reUserPhone)){
            return ResponseUtil.fail("请填写推荐人手机号");
        }

        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user) {
            return ResponseUtil.fail("选择的用户不存在");
        }
        if(!user.getRecodeUserId().equals(0)){
            return ResponseUtil.fail("该用户已有推荐人");
        }

        DtsUserExample example = new DtsUserExample();
        example.orderBy("id desc");
        example.createCriteria().andMobileEqualTo(reUserPhone);
        DtsUser reuser = userMapper.selectOneByExample(example);
        if (null == reuser) {
            return ResponseUtil.fail("推荐人不存在");
        }
        if(reuser.getId().equals(user.getId())){
            return ResponseUtil.fail("不能绑定自己为推荐人");
        }

        DtsUser userUpd=new DtsUser();
        userUpd.setId(user.getId());
        userUpd.setRecodeUserId(reuser.getId());
        userUpd.setRecodeBindTime(LocalDateTime.now());
        userMapper.updateByPrimaryKeySelective(userUpd);

        return ResponseUtil.ok("绑定成功");
    }
    /**
     * 获取用户嗨币信息
     *
     * @param userId
     * @return
     */
    public Object getUserCommissionInfo(Integer userId) {
        DtsUserExample example = new DtsUserExample();
        example.createCriteria().andIdEqualTo(userId);
        DtsUser user = userMapper.selectOneByExample(example);
        if (null == user) {
            return ResponseUtil.fail("账号不存在");
        }
        Map<String, Object> result = new HashMap<>();
        result.put("commission", user.getCommission());//当前可提现嗨币
        result.put("commissionSumCount", userCommissionDetaiMapperEx.getUserCommissionSumCount(userId));//嗨币总数
        result.put("toDayCommissionSumCount", userCommissionDetaiMapperEx.getUserToDayCommissionSumCount(userId));//今日嗨币
        result.put("dividend", userCommissionDetaiMapperEx.getUserDividendSumCount(userId));//分红
        result.put("managementAward", userCommissionDetaiMapperEx.getUserManagementAwardSumCount(userId));//管理奖
        result.put("monthCommissionSumCount", userCommissionDetaiMapperEx.getUserMonthCommissionSumCount(userId));//月嗨币总数
        return ResponseUtil.ok(result);
    }

    /**
     * 获取用户团队列表
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public TableDataInfo getUserTeamList(Integer page, Integer size, Integer userId) {
        if (null == userId) {
            return TableDataInfo.errorDataTable("请选择用户");
        }
        Page p = PageHelper.startPage(page, size);
        List<WxUserTeamVo> list = dtsUserMapperEx.getUserTeamList(userId);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        } else {
            list.forEach(item -> {
                if (null != item.getVipType() && null == VipTypeEnums.getEnum(item.getVipType())) {
                    item.setVipType(null);
                }
            });
        }
        Map<String, Object> append = new HashMap<>();
        append.put("teamSumCommission", dtsUserMapperEx.getTeamSumCommission(userId));//团队嗨币总数
        append.put("monthTeamSumCommission", dtsUserMapperEx.getMonthTeamSumCommission(userId));//团队月嗨币总数
        return TableDataInfo.getDataTable(list, p.getTotal(), append);
    }

    /**
     * 获取用户嗨币明细列表
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public TableDataInfo getUserCommissionDetailList(Integer page, Integer size, Integer userId) {
        if (null == userId) {
            return TableDataInfo.errorDataTable("请选择用户");
        }
        Page p = PageHelper.startPage(page, size);
        List<WxUserCommissionDetailDto> list = userCommissionDetaiMapperEx.getUserCommissionDetailList(userId);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }

    /**
     * 获取用户积分明细列表
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public TableDataInfo getUserPointsDetailList(Integer page, Integer size, Integer userId) {
        if (null == userId) {
            return TableDataInfo.errorDataTable("请选择用户");
        }
        DtsPointsDetailExample query = new DtsPointsDetailExample();
        query.setOrderByClause("add_time desc,id desc");
        query.createCriteria().andUserIdEqualTo(userId);
        Page p = PageHelper.startPage(page, size);
        List<DtsPointsDetail> list = dtsPointsDetailMapper.selectByExample(query);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        } else {
            list.forEach(item -> {
                //不返回相关用户id
                item.setUserId(null);
                item.setToUserId(null);
            });
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }


    /**
     * 用户列表
     *
     * @param status
     * @param nickname
     * @param phone
     * @param page
     * @param size
     * @return
     */
    public TableDataInfo getUserList(Integer status, String nickname, String phone, Integer page, Integer size) {
        DtsUserExample example = new DtsUserExample();
        example.orderBy("add_time desc");
        DtsUserExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        if (null != status) {
            criteria.andStatusEqualTo(status.byteValue());
        }
        if (!StringUtil.isBlank(phone)) {
            criteria.andMobileEqualTo(phone);
        }
        if (!StringUtil.isBlank(nickname)) {
            criteria.andNicknameLike("%" + nickname + "%");
        }
        example.or(criteria);
        Page p = PageHelper.startPage(page, size, true);
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<DtsUser> list = userMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(user -> {
                DtsUser reUser = userMapper.selectByPrimaryKey(user.getRecodeUserId());

                //敏感信息不显示
                user.setWeixinOpenid(null);
                Map<String, Object> userInfo = JSON.parseObject(JSON.toJSONString(user));
                userInfo.put("reUser", reUser);//推荐人信息
                userInfo.put("commission", user.getCommission());//当前可提现嗨币
                userInfo.put("commissionSumCount", userCommissionDetaiMapperEx.getUserCommissionSumCount(user.getId()));//嗨币总数
                userInfo.put("toDayCommissionSumCount", userCommissionDetaiMapperEx.getUserToDayCommissionSumCount(user.getId()));//今日嗨币
                userInfo.put("dividend", userCommissionDetaiMapperEx.getUserDividendSumCount(user.getId()));//分红
                userInfo.put("managementAward", userCommissionDetaiMapperEx.getUserManagementAwardSumCount(user.getId()));//管理奖

                resultList.add(userInfo);
            });
        }
        return TableDataInfo.getDataTable(resultList, p.getTotal());
    }

    /**
     * 启用禁用
     *
     * @param userId
     * @param status
     * @return
     */
    public Object updateUserStatus(Integer userId, Integer status) {
        RLock lock = redisson.getLock("admin_updateUserStatus_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent("其他管理人员操作中,请稍后再试");
        }
        lock.lock(30, TimeUnit.SECONDS);
        if (status != 0 && status != 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【status】错误");
        }
        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user || user.getDeleted()) {
            lock.unlock();
            return ResponseUtil.fail("用户不存在或已被删除");
        }
        user.setStatus(status.byteValue());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateByPrimaryKeySelective(user);
        if (status == 1) {//如果当前操作为禁用，那就删除用户缓存
            String key = MessageFormat.format(RedisKeyConsts.WX_LOGIN_USER, new Object[]{String.valueOf(userId)});
            redisCache.deleteObject(key);
        }
        lock.unlock();
        return ResponseUtil.ok(status == 1 ? "禁用成功" : "启用成功", null);
    }
}
